/**
 * @fileoverview Giant Interective Group, Inc. Javascript Library v2.0.5.
 * 该Javascript库是基于jQuery的扩展。
 * <pre>
 * Copyright (C) 2004-2009 Giant Interective Group, Inc. All rights reserved.
 * 版权所有 2004-2009 上海巨人网络科技有限公司
 * </pre>
 * 
 * @version 2.0.5, 2009-06-05 04:08:30
 * @author  Fuchun
 */

/**
 * @namespace Giant Ajax Framework API 的根名称空间。
 */
var giant = {};
/**
 * Giant UI Library Version.
 * @type String
 */
giant.version = '2.0.5';
window.giant = giant;

/**
 * 创建一个新的StringBuilder实例。
 * @class
 * 一个类似于java.lang.StringBuffer的可变字符序列。
 * @example
 * var sb = new StringBuilder();
 * sb.append('&lt;div id="div1"&gt;\n');
 * sb.append('  &lt;h2&gt;this is a h2 title.&lt;/h2&gt;\n');
 * sb.append('&lt;/div&gt;\n');
 * var shtml = sb.toString();
 * // shtml为: &quot;&lt;div id="div1"&gt;\n  &lt;h2&gt;this is a h2 title.&lt;/h2&gt;\n&lt;/div&gt;&quot;
 * </pre>
 * @constructor
 * @name StringBuilder
 * @param {Object} o 要添加到序列首部的对象。
 * @returns {StringBuilder}的新实例。
 */
function StringBuilder(o) {
    this.__strings__ = [];
    if( o )
        this.append(o);
};

/**#@+
 * @memberOf StringBuilder
 * @method
 */
StringBuilder.prototype = {
    /**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
     * 追加<tt>Object</tt>参数的字符串表示形式。
     * <pre>参数将被转换成字符串，就好象使用了 o.toString() 方法一样。然后，将所得字符串中的字符追加到此序列。</pre>
     * @param {Object} o 一个Object
     * @returns 返回这个 <code>StringBuilder</code> 对象的一个引用。
     * @type StringBuilder
     */
    append: function(o) {
        if( !o )
            return this;
        if( Object.prototype.toString.call(o) === '[object Array]' )
            this.__strings__.push(o.join('').toString());
        else
            this.__strings__.push(o.toString());
        return this;
    },
    
    /**
     * 清空此字符序列。
     * @type void
     */
    clear: function() { this.__strings__ = []; },
    
    /**
     * 返回长度（字符数）。
     * <pre>该长度与给定的表示编码的参数有关。在UTF-8编码中，一个全角字符表示3个英文字符。
     * 不指定字符编码情况下，默认为正常的长度，即所有字符的长度为1。</pre>
     * @param {boolean} b 是否使用UTF-8字符编码解析序列长度。
     * @returns {Number} 返回给定字符编码的此序列的长度。
     */
    length: function(b) {
        if( arguments.length == 0 )
            b = false;
        var s = this.toString();
        if( b )
            return s.replace(/[^\x00-xFF]/g,'***').length;
        return s.length;
    },
    
    /**
     * 返回此序列中数据的字符串表示形式。
     * <pre>分配一个新的 String 对象，并将它初始化，以包含当前由此对象表示的字符串序列。然后返回此 String。
     * 对此序列的后续更改不影响该 String 的内容。</pre>
     * 
     * @return {String} 字符序列的字符串表示形式。
     */
    toString: function() {
        var __newString__ = this.__strings__.join('');
        return __newString__;
    }
};
/**#@-*/

(function($){

var __tostr__ = Object.prototype.toString, undefined, window = this;
if(window.Document) { // 在FireFox中模拟IE的DOMDocument的方法
    /**
     * @class Definition Firefox Own Document Class.
     * <pre>这个类中额外注入的方法属于Mozilla(Firefox)专有，它用于模拟IE下的DOM模型。
     * 使得在Mozilla(Firefox)浏览器下使用Dom模型，和IE是一样的。</pre>
     * @name Document
     */

    /**#@+
     * @memberOf Document
     * @name method
     */
    
    /** 在<strong>Mozilla(Firefox)</strong>中模拟IE DOM中的readyState属性。
     * @field
     */
    Document.prototype.readyState = 0;
    /** 在<strong>Mozilla(Firefox)</strong>中模拟IE DOM中的onreadystatechange
     * @function */
    Document.prototype.onreadystatechange = null;
    /** 模拟并执行onreadystatechange
     * @private */
    Document.prototype.__changeReadyState__ = function (iReadyState) {
        this.readyState = iReadyState;
        if(typeof this.onreadystatechange == "function") {
            this.onreadystatechange();
        }
    };
    /** 模拟IE DOM中的parseError 
     * @private */
    Document.prototype.__initError__ = function() {
        this.parseError.errorCode = 0;
        this.parseError.filepos = -1;
        this.parseError.line = -1;
        this.parseError.linePos = -1;
        this.parseError.reason = null;
        this.parseError.srcText = null;
        this.parseError.url= null;
    };
    /** @private */
    Document.prototype.__checkForErrors__ = function() {
        if(this.documentElement.tagName == "parseerror") {
            var errorReg = />([\s\S]*?)location:([\s\S]*?)Line Number (\d+),Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
            errorReg.test(this.xml);
            this.parseError.errorCode = -999999;
            this.parseError.reason = RegExp.$1;
            this.parseError.url= RegExp.$2;
            this.parseError.line = parseInt(RegExp.$3);
            this.parseError.linePos = parseInt(RegExp.$4);
            this.parseError.srcText = RegExp.$5;
        }
    };
    /** 模拟IE DOM中的loadXML方法 
     * @param {String} sXml 要载入的XML格式的字符串。*/
    Document.prototype.loadXML = function (sXml) {
        this.__initError__();
        this.__changeReadyState__(1);
        var parser = new DOMParser();
        var xmlDoc = parser.parseFromString(sXml, "text/xml");
        while(this.firstChild) {
            this.removeChild(this.firstChild);
        }
        
        for(var i = 0; i < xmlDoc.childNodes.length; i++) {
            var newNode = this.importNode(xmlDoc.childNodes[i], true);
            this.appendChild(newNode);
        }
        
        this.__checkForErrors__();
        this.__changeReadyState__(4);
    };
    //  模拟IE DOM中的load方法
    Document.prototype.__load__ = Document.prototype.load;
    /**  模拟IE DOM中的load方法 
     * @param {String} sURL 要载入的XML文件的URL地址。*/
    Document.prototype.load = function (sURL) {
        this.__initError__();
        this.__changeReadyState__(1);
        this.__load__(sURL);
    };
    /**#@-*/
    // 模拟IE DOM中的.xml属性
    Node.prototype.__defineGetter__("xml", function() {
        var oSerializer = new XMLSerializer();
        return oSerializer.serializeToString(this, "text/xml");
    });
}

if( window.HTMLElement ) {
    HTMLElement.prototype.__defineSetter__("outerHTML", function(sHTML) {
        var r = this.ownerDocument.createRange();
        r.setStartBefore(this);
        var df = r.createContextualFragment(sHTML);
        this.parentNode.replaceChild(df,this);
        return sHTML;
    });
    
    HTMLElement.prototype.__defineGetter__("outerHTML",function(){
        var attr;
        var attrs = this.attributes;
        var str = "<" + this.tagName.toLowerCase();
        for(var i = 0; i < attrs.length; i++) {
            attr = attrs[i];
            if(attr.specified)
            str += " " + attr.name + '="' + attr.value + '"';
        }
        if(!this.canHaveChildren) return str + ">";
        return str + ">" + this.innerHTML + "</" + this.tagName.toLowerCase() + ">";
    });
    
    HTMLElement.prototype.__defineGetter__("canHaveChildren", function() {
        switch(this.tagName.toLowerCase()){
            case "area":
            case "base":
            case "basefont":
            case "col":
            case "frame":
            case "hr":
            case "img":
            case "br":
            case "input":
            case "isindex":
            case "link":
            case "meta":
            case "param":
            return false;
        }
        return true;
    });
}

/**#@+
 * <italic>给 <strong>Object</strong> 类额外添加的方法。</italic>
 * @memberOf Object
 * @method
 */

/**
 * 用于对象属性的快速复制(继承)。将<tt>source</tt>的属性或方法复制(继承)到对象
 * <tt>target</tt>中，若<tt>deep</tt>为<code>true</code>，则子对象的子属性
 * 也一起被复制(继承)。相同属性的将会被<tt>source</tt>中的新属性覆盖。
 * @example
 * var source = {id:1, name:'Jack Source'}, target = {name:'Jack Target', gender:1};
 * var newObj1 = Object.extend(target, source);
 * // newObj1  --&gt;&gt;  {id:1, name:'Jack Source', gender:1}
 * Object.extend(target);
 * // Object.name   --&gt;&gt;  'Jack Target'
 * // Object.gender --&gt;&gt;  1
 * 
 * @param {Object} target 目标对象。
 * @param {Object} source 源对象。
 * @param {boolean} deep 是否复制(继承)对象中的对象。
 * @returns {Object} 返回继承了<tt>source</tt>对象属性的新对象。
 */
Object.extend = function(target, /*optional*/source, /*optional*/deep) {
    target = target || {};
    var sType = typeof source, i = 1, options;
    if( sType === 'undefined' || sType === 'boolean' ) {
        deep = sType === 'boolean' ? source : false;
        source = target;
        target = this;
    }
    if( typeof source !== 'object' && 
            __tostr__.call(source) !== '[object Function]' )
        source = {};
    
    while(i <= 2) {
        options = i === 1 ? target : source;
        if( options != null ) {
            for( var name in options ) {
                var src = target[name], copy = options[name];
                if(target === copy)
                    continue;
                if(deep && copy && typeof copy === 'object' && !copy.nodeType)
                    target[name] = this.extend(src || 
                            (copy.length != null ? [] : {}), copy, deep);
                else if(copy !== undefined)
                    target[name] = copy;
            }
        }
        i++;
    }
    return target;
};

/**
 * 将给定的对象，转换成<code>JSON</code>格式字符串。
 * @param {Object} o 要转换成<code>JSON</code>的Javascript对象。
 * @returns {String} 返回给定的Javascript对象的<code>JSON</code>格式的字符串。
 */
Object.toJSON = function(o) {
    var t = typeof o;
    switch( t ) {
        case 'undefined':
        case 'function':
        case 'unknown':
        return 'null';
        case 'boolean':
        return o.toString();
    }
    
    if( o === null || (o && o.nodeType == 1) ) return 'null';
    if( typeof o.toJSON === 'function' )
        return o.toJSON();
    var ret = [], name, val;
    for( var key in o ) {
        t = typeof key;
        if( t === 'number' )
            name = '"' + key + '"';
        else if( t === 'string' )
            name = key.quote();
        else continue;
        val = Object.toJSON( o[key] );
        if(typeof val !== 'undefined')
            ret.push(name + ':' + val);
    }
    return '{' + ret.join(',') + '}';
};
/**#@-*/

/** <strong>捕捉script标签</strong>的正则表达式常量。
 * @type RegExp */
RegExp.ScriptExpr = /<script[^>]*>([\S\s]*?)<\/script>/igm;

/** 表示为<strong>&quot;null&quot;</strong>的字符串常量。
 * @type String */
String.Null = 'null';
/** 表示为<strong>空字符串 &quot;&quot;</strong>的字符串常量。
 * @type String */
String.Empty = '';
/** 表示为<strong>特殊字符</strong>的字符串Hash组。
 * @type Object */
String.SpecialChars = {
    '\b' : '\\b', '\t' : '\\t', '\n' : '\\n',
    '\f' : '\\f', '\r' : '\\r', '\\' : '\\\\'
};

Object.extend(String.prototype,
/** @lends String */
{
    /**
     * 返回字符串的副本，<strong>用引号引用此字符串</strong>。
     * @returns {String} 被双引号引用的字符串。
     */
    quote: function() {
        var reEscapeable = /[\"\\\x00-x1f\x7f-\x9f]/g;
        if( reEscapeable.test(this) ) {
            return '"' + this.replace(reEscapeable, function(a) {
                var c = String.SpecialChars[a];
                if( typeof c === 'string' )
                    return c;
                c = a.charCodeAt();
                return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
            }) + '"';
        }
        return '"' + this + '"';
    },
    /**
     * 返回字符串的副本，忽略前导空白和尾部空白。
     * @returns {String} 此字符串移除了前导和尾部空白，如果没有前导和尾部空白字符，则返回此字符串。
     */
    trim: function() { return this.replace(/^\s+|\s+$/g, ''); },
    /**
     * 返回字符串的副本，忽略前导空白。
     * @returns {String} 此字符串移除了前导空白，如果没有前导空白字符，则返回此字符串。
     */
    ltrim: function() { return this.replace(/^\s+/g, ''); },
    /**
     * 返回字符串的副本，忽略尾部空白。
     * @returns {String} 此字符串移除了尾部空白，如果没有尾部空白字符，则返回此字符串。
     */
    rtrim: function() { return this.replace(/\s+$/g, ''); },
    /**
     * 返回字符串的副本，忽略前导空白和尾部空白。
     * @returns {String} 
     * @see 见<a href="#trim">trim()<a>
     */
    strip: function() { return this.trim(); },
    /**
     * 返回字符串的副本，忽略字符串内部的含有的所有标签字符串。
     * @param {String} replacement 用于替换标签的指定字符串。
     * @returns {String} 此字符串移除了所有的表为HTML标签的字符，如没有标签字符，则返回此字符串。
     */
    stripTags: function(replacement) {
        return this.replace(/<\/?[^>]+>/ig, (replacement || ''));
    },
    /**
     * 返回字符串的副本，忽略字符串的HTML的Script标签字符串。
     * @param {String} replacement 用于替换标签的指定字符串。
     * @returns {String} 此字符串移除了所有的表示为HTML的Script标签的字符，如没有Script标签，则返回此字符串。
     */
    stripScript: function(replacement) {
        return this.replace(new RegExp(RegExp.ScriptExpr, 'igm'), (replacement || ''));
    },
    /**
     * 返回字符串的副本，字符串中的特定字符将被转换。<a href="#unescapeHTML">unescapeHTML</a> 方法可还原经该方法转换的字符串。
     * @example
     * <pre>
     * &amp;  --&gt;  &amp;amp;
     * &lt;  --&gt;  &amp;lt;
     * &gt;  --&gt;  &amp;&gt;
     * &quot;  --&gt;  &amp;quot;
     * &#39;  --&gt;  &amp;#39;
     * </pre>
     * @returns {String} 此字符串将转换特定的字符，如没有那些字符，则返回此字符串。
     */
    escapeHTML: function() {
        return this.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
                .replace(/\"/g, '&quot;').replace(/\'/g, '&#39;');
    },
    /**
     * 返回字符串的副本，字符串中的特定字符将被转换，<a href="#escapeHTML">escapeHTML</a> 方法可还原经该方法转换的字符串。
     * @example
     * <pre>
     * &amp;amp;  --&gt;  &amp;
     * &amp;lt;   --&gt;  &lt;
     * &amp;gt;   --&gt;  &gt;
     * &amp;quot; --&gt;  &quot;
     * &amp;#39;  --&gt;  &#39;
     * </pre>
     * @returns {String} 此字符串将转换特定的字符，如没有那些字符，则返回此字符串。
     */
    unescapeHTML: function() {
        return this.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>')
                .replace(/&quot;/g, '"').replace(/&#39;/g, '\'');
    },
    /**
     * 返回字符串的副本，字符串中的格式字符将被转换。
     * @example
     * <pre>
     * // <strong>reverse == true</strong>时，以下字符将被转换：
     * &lt;br /&gt;  --&gt;  \n
     * &amp;nbsp;  --&gt;  _ (表示一个空格)
     * &amp;       --&gt;  &amp;amp;
     * // <strong>reverse == false</strong>时，以下字符将被转换：
     * &amp;amp;       --&gt;  &amp;
     * _(blank)    --&gt;  &amp;nbsp;
     * \r\n        --&gt;  \n
     * \n          --&gt;  &lt;br /&gt;
     * </pre>
     * @param {Boolean} reverse 指示是否使用反向转换。
     * @returns {String} 此字符串将转换格式字符，如没有格式字符，则返回此字符串。
     */
    formatHTML: function(reverse) {
        var str = this.toString();
        if( reverse ) {
            str = str.replace(/<br[^>]*>/gm, '\n').replace(/&nbsp;/gm, ' ').replace(/&/gm, '&amp;');
        } else {
            str = str.replace(/&amp;/gm, '&').replace(/ /gm, '&nbsp;').replace(/\r\n/gm, '\n')
                    .replace(/\n/gm, '<br />');
        }
        return str;
    },
    /**
     * 返回字符串的长度，若指定 <tt>b</tt> ，则返回UTF-8编码的字符串长度。
     * @param {boolean} b 是否返回UTF-8编码的字符串长度。
     * @returns {Number} 返回字符串的长度。
     */
    len: function(b) {
        if( b ) {
            var s = this.toString();
            return s.replace(/[^\x00-\xFF]/g, '***').length;
        }
        return this.length;
    },
    /**
     * 将CSS样式的短线属性转换为Camel的命名样式。
     * <pre>
     * background-color  --&gt;  backgroundColor
     * border-top-color  --&gt;  borderTopColor
     * </pre>
     * @returns {String} 新的字符串，它移除原字符串的短线 <code>-</code>，并将短线后第一个字符转为大写。
     */
    toCamel: function() {
        var aParts = this.split('-'), iLen = aParts.length;
        if( iLen == 1 ) return aParts[0];
        
        var camelized = this.charAt(0) === '-' ? aParts[0].charAt(0).toUpperCase() + 
                aParts[0].substring(1) : aParts[0];
        for( var i = 1; i < iLen; i++ )
            camelized += aParts[i].charAt(0).toUpperCase() + aParts[i].substring(1);
        return camelized;
    },
    /**
     * 测试此字符串是否以指定的前缀开始。
     * @param {String} p 指定的前缀。
     * @returns {boolean} 如果该参数表示的字符序列是此字符串表示的字符序列的前缀，则为<code>true</code>，
     *   否则为<code>false</code>。还要注意，如果参数是空字符串，则返回<code>true</code>。
     */
    startsWith: function(p) {
        return p === '' ? true : (this.indexOf(p) === 0);
    },
    /**
     * 测试此字符串是否以指定的后缀结束。
     * @param {String} p 指定的后缀。
     * @returns {boolean} 如果该参数表示的字符序列是此字符串表示的字符序列的后缀，则为<code>true</code>，
     *   否则为<code>false</code>。还要注意，如果参数是空字符串，则返回<code>true</code>。
     */
    endsWith: function(p) {
        if( p === '' ) return true;
        var d = this.length - p.length;
        return d >= 0 && this.lastIndexOf(p) === d;
    },
    /**
     * 测试此字符串是否是一串空格组成的空字符串。
     * @returns {boolean} 如果该字符串是一串字可知组成的字符串，则为<code>true</code>，否则为<code>false</code>。
     */
    isBlank: function() { return this.length > 0 && /^\s*$/.test(this); },
    /**
     * 测试此字符串是否是一个正确格式的Email。
     * @returns {boolean} 如果该字符串是一个正确格式的Email，则为<code>true</code>，否则为<code>false</code>。
     */
    isEmail: function() { return (/^(?:\w+\.?)*\w+@(?:\w+\.?)*[a-zA-Z]{2,3}$/i).test(this.trim()); },
    /**
     * 测试此字符串是否是空字符串。
     * @returns {boolean} 如果该字符串是空字符串，则为<code>true</code>，否则为<code>false</code>。
     */
    isEmpty: function() { return this === String.Empty; },
    /**
     * 测试此字符串是否全部由数字组成。
     * @returns {boolean} 如果该字符串全部由数字组成，则为<code>true</code>，否则为<code>false</code>。
     */
    isNumber: function() { return /^\d+$/.test(this); },
    /**
     * 测试此字符串是否为合法的变量命名。
     * @returns {boolean} 如果该字符串为合法的变量命名格式，则为<code>true</code>，否则为<code>false</code>。
     */
    isVar: function() { return /^[a-zA-Z]\w+$/.test(this); },
    /**
     * 将此字符串转换成<code>JSON</code>格式。
     * @returns {String} 此字符串的<code>JSON</code>格式的副本。
     */
    toJSON: function() { return this.quote(); }
}, true);

/**#@+
 * <italic>给 <strong>Array</strong> 类额外添加的方法。</italic>
 * @memberOf Array
 * @method
 */

/**
 * 将此数组转换成<code>JSON</code>格式的字符串。
 * @returns {String} 返回<code>JSON</code>格式的字符串。
 */
Array.prototype.toJSON = function() {
    var ret = [], i = 0, len = this.length;
    for( ; i < len; i++ )
        ret.push(Object.toJSON(this[i]));
    return '[' + ret.join(',') + ']';
};
/**
 * 轮询数组的便捷方法。
 * @param {Function} callback 轮询数组项要执行的回调函数。
 * @param {Array} args 轮询数组时传入的参数集。
 * @returns {Array} 返回此数组的引用。
 */
Array.prototype.each = function(callback, args) {
    var i = 0, len = this.length;
    if( args ) {
        for( ; i < len; )
            if( callback.apply(this[i++], args) === false )
                break;
    } else {
        for( var value = this[0];
                i < len && callback.call(value, i, value) !== false; value = this[++i] ){} 
    }
    return this;
};
/**
 * 将此数组转换成新的数组，数组项的值由<tt>callback</tt>回调函数计算所得。
 * @param {Function} callback 轮询数组执行的回调函数。
 * @returns {Array} 一组新值的新数组对象。
 */
Array.prototype.map = function(callback) {
    var len = this.length, i = 0;
    var ret = [];
    for( ; i < len; i++ )
        ret[i] = callback.call(this[i], i);
    return ret;
};
/**
 * 筛选出与指定回调函数返回值匹配的元素集合。
 * @param {Function} callback 轮询数组执行的回调函数。
 * @returns {Array} 一组新的数组对象。
 */
Array.prototype.filter = function(callback) {
    var len = this.length, i = 0, ret = [];
    for( ; i < len; i++ )
        if( callback.call(this[i], i) )
            ret[ret.length] = this[i];
    return ret;
};
/**
 * 清除此数组的所有项。
 * @returns {Array} 返回此数组的引用。
 */
Array.prototype.clear = function() {
    this.splice(0, this.length);
    return this;
};
/**
 * 返回此数组的第一项。
 * @returns {Object} 返回此数组的第一项。
 */
Array.prototype.first = function() {
    return this.length > 0 ? this[0] : null;
};
/**
 * 返回此数组的最后一项。
 * @returns {Object} 返回此数组的最后一项。
 */
Array.prototype.last = function() {
    return this.length > 0 ? this[this.length - 1] : null;
};
/**#@-*/

/**#@+
 * <italic>给 <strong>Number</strong> 类额外添加的方法。</italic>
 * @memberOf Number
 * @method
 */
/**
 * 返回此数字的字符串，如果数字小于10，则数字前补0。
 * @returns {String} 
 */
Number.prototype.filled = function() {
    return this > 9 ? this.toString() : '0' + this.toString();
};
/**
 * 返回HTML格式十六进制颜色的一部份，可能是R、G或B，它的值域为[0, 255]。
 * @returns {String} 此数字表示的16进制字符串。
 */
Number.prototype.toColorHex = function() {
    if( this > 255 ) return 'FF';
    var s = this.toString(16);
    return s.length > 1 ? s : '0' + s.toUpperCase();
};
/**
 * 返回此数字的JSON格式字符串。
 * @returns {String} 此数字表示的JSON格式的字符串。
 */
Number.prototype.toJSON = function() {
    return isFinite(this) ? this.toString() : '';
};
/**#@-*/

/**#@+
 * <italic>给 <strong>Date</strong> 类额外添加的方法。</italic>
 * @memberOf Date
 * @method
 */
if( !Date.now )
    // 仅内部使用的便捷方法。
    Date.now = function() { return new Date(); };

/**
 * 将此<code>Date</code>对象，转换成<code>JSON</code>格式字符串。
 * @return (String) 返回此<code>Date</code>的<code>JSON</code>格式字符串。
 */
Date.prototype.toJSON = function() {
    return this.getFullYear() + '-' + this.getMonth().filled() + '-' + this.getDate().filled + ' ' +
            this.getHours().filled() + ':' + this.getMinutes().filled() + ':' + 
            this.getSeconds().filled() + ',' + this.getMilliseconds().filled();
};
/**#@-*/

if( typeof Element === 'undefined' )
    /**
     * @class the Element of the Document
     * @name Element
     */
    var Element = {};
/**
 * 表示<strong>控件 的disabled属性名称</strong>的字符串常量。
 * @type String */
Element.Disabled = 'disabled';
/**
 * 表示<strong>input 的readonly属性名称</strong>的字符串常量。
 * @type String */
Element.Readonly = 'readonly';
/**
 * 表示<strong>input[type=radio|checkbox] 的checked属性名称</strong>的字符串常量。
 * @type String */
Element.Checked = 'checked';

giant.extend = Object.extend;
/**
 * document.getElementById方法的简单封装。
 * @example
 * <pre>
 * 快捷方式：<strong>E</strong>
 * // &lt;div id="div1"&gt;&lt;/div&gt;
 * E("div1").style.backgroundColor = '#ffffff';
 * </pre>
 * @param {String|Object} o 元素Id或者元素对象。
 * @param {Document} doc 指定的Document对象。
 * @type Element
 */
giant.E = function(o, doc) {
    if(typeof o === 'object' && o.nodeType === 1)
        return o;
    if(doc)
        return doc.getElementById(o);
    else
        return document.getElementById(o);
};
window.E = giant.E;
var __userAgent__ = navigator.userAgent.toLowerCase();
/** 
 * @class 浏览器判断的便捷工具类。
 * 另一个引用的快捷方式：<code>B.msie、B.version、B.safari……</code>
 * @name giant.B */
giant.B = {};
/** 浏览器版本。
 * @type String */
giant.B.version = (__userAgent__.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1];
/** 是否是Safari浏览器。
 * @type Boolean */
giant.B.safari = /webkit/.test( __userAgent__ );
/** 是否是Opera浏览器。
 * @type Boolean */
giant.B.opera = /opera/.test( __userAgent__ );
/** 是否是IE浏览器。
 * @type Boolean */
giant.B.msie = /msie/.test( __userAgent__ ) && !/opera/.test( __userAgent__ );
/** 是否是Mozilla浏览器。
 * @type Boolean */
giant.B.mozilla = /mozilla/.test( __userAgent__ ) && !/(compatible|webkit)/.test( __userAgent__ );
window.B = giant.B;

/**
 * 一个空函数引用。
 * @field
 * @type Function
 */
giant.EmptyFn = function() {};
/**
 * 若指定的对象 <tt>o</tt> 是一个布尔值对象，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isBool = function(o) { return typeof o === 'boolean'; };
/**
 * 若指定的对象 <tt>o</tt> 是一个HTMLElement对象，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isElement = function(o) { return o && o.nodeType === 1; };
/**
 * 若指定的对象 <tt>o</tt> 是一个空字符串或者是一个长度为0的数组，则返回 <code>true</code>，否则返回 <code>false</code> .
 * @param {Object} o 要检查的对象 .
 * @type Boolean
 */
giant.isEmpty = function(o) {
    return giant.isArray(o) ? o.length === 0 : (giant.isString(o) ? o === String.Empty : false);
};
/**
 * 若指定的对象 <tt>o</tt> 是一个null值或者空字符串或者是一个长度为0的数组，则返回 <code>true</code>，否则返回 <code>false</code> .
 * @param {Object} o 要检查的对象 .
 * @type Boolean
 */
giant.isNullOrEmpty = function(o) {
    return (o == null || this.isEmpty(o));
};
/**
 * 若指定的对象 <tt>o</tt> 是一个字符串，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isString = function(o) { return typeof o === 'string'; };
/**
 * 若指定的对象 <tt>o</tt> 是一个数组，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isArray = function(o) { return __tostr__.call(o) === '[object Array]'; };
/**
 * 若指定的对象 <tt>o</tt> 是一个函数，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isFunction = function(o) { return __tostr__.call(o) === '[object Function]'; };
/**
 * 若指定的对象 <tt>o</tt> 是一个数字，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isNumber = function(o) { return typeof o === "number" && isFinite(o); };
/**
 * 若指定的对象 <tt>o</tt> 是一个undefined，则返回 <code>true</code>，否则返回 <code>false</code>。
 * @param {Object} o 要检查的对象。
 * @type Boolean
 */
giant.isUndef = function(o) { return typeof o === 'undefined'; };
/**
 * 生成一个随机字符，该随机字符范围是[0-9a-zA-Z]。
 * @type String
 */
giant.randomChar = function() {
    var rand = Math.round(Math.random() * 2), itmp = 0, ctmp = '\u0000';
    switch( rand ) {
        case 1:
        itmp = Math.round(Math.random() * 25 + 65);
        ctmp = String.fromCharCode(itmp);
        return ctmp;
        case 2:
        itmp = Math.round(Math.random() * 25 + 97);
        ctmp = String.fromCharCode(itmp);
        return ctmp;
        default:
        itmp = Math.round(Math.random() * 9);
        return itmp + "";
    }
};
/**
 * 一个封装的轮询方法。封装了<code>setInterval</code>或者<code>setTimeout</code>。
 * 当参数中的<code>options.poll</code>为<code>true</code>时，将执行<code>setInterval</code>。
 * @param {Object} options 
 *                 <code>options.time</code> - 间隔的时间(单位：秒)<br>
 *                 <code>options.poll</code> - 是否无限论询(默认为<code>false</code>)<br>
 *                 <code>options.fn</code>   - 轮询执行的回调函数(<strong><italic>该参数已不建议再使用，使用options.callback代替</italic></strong>)
 *                 <code>options.callback</code> - 轮询执行的回调函数。
 * @param {Array} args 轮询执行的回调函数的参数集。
 * @returns {Object} 返回时间器(setInterval或setTimeout)对象。
 */
giant.interval = function(options, args) {
    options = giant.extend({
        time: 10,
        poll: false,
        callback: function() {}
    }, options || {});
    if(!giant.isArray(args))
        args = [];
    var timer = null;
    if( options.poll ) {
        timer = setInterval(function() {
            if(giant.isFunction(options.fn))
                options.fn.apply(giant, args);
            else if(giant.isFunction(options.callback))
                options.callback.apply(giant, args);
        }, options.time * 1000);
    } else {
        timer = setTimeout(function() {
            if(giant.isFunction(options.fn))
                options.fn.apply(giant, args);
            else if(giant.isFunction(options.callback))
                options.callback.apply(giant, args);
        }, options.time * 1000);
    }
    return timer;
};

/**
 * @namespace Giant UI Library Dom类相关操作和属性的名称空间。
 */
giant.dom = {
    /**
     * 获取或设置浏览器窗口的纵向滚动条移动的距离。
     * @param {Number} val 要设置的浏览器窗口的纵向滚动条距顶部的距离。
     * @param {Function} callback 设置完距离之后执行的回调函数。
     * @returns {Number} 浏览器窗口的纵向滚动条移动的距离。
     */
    scrollTop: function(val, callback) {
        if(val) {
            $(window).scrollTop(val);
            if(giant.isFunction(callback))
                callback.call(this, $(window).scrollTop());
        } else
            return $(window).scrollTop();
    },
    /**
     * 获取或设置浏览器窗口横向滚动条移动的距离。
     * @param {Number} val 要设置的浏览器窗口的横向滚动条距左边的距离。
     * @param {Function} callback 设置完距离之后执行的回调函数。
     * @returns {Number} 浏览器窗口的横向滚动条移动的距离。
     */
    scrollLeft: function(val, callback) {
        if(val) {
            $(window).scrollLeft(val);
            if(giant.isFunction(callback))
                callback.call(this, $(window).scrollLeft());
        } else
            return $(window).scrollLeft();
    },
    /**
     * 返回当前浏览器视窗的宽度，单位：px。
     * @returns {Number} 当前视窗的宽度(不包括滚动条移动的距离)
     */
    clientWidth: function() { return $(window).width(); },
    /**
     * 返回当前浏览器视窗的高度，单位：px。
     * @returns {Number} 当前视窗的高度(不包括滚动条移动的距离)
     */
    clientHeight: function() { return $(window).height(); },
    /**
     * 返回当前HTML文档的实际宽度，单位：px。
     * @returns {Number} 当前HTML文档的实际宽度。
     */
    documentWidth: function() { return $(document).width(); },
    /**
     * 返回当前HTML文档的实际高度，单位：px。
     * @returns {Number} 当前HTML文档的实际高度。
     */
    documentHeight: function() { return $(document).height(); },
    /**
     * 获取或设置指定元素的样式。
     * @example
     * <pre>
     * // 设置div1元素的背景颜色为黑色，执行之后打印一段信息。
     * giant.dom.css('#div1', {backgroundColor:'#000000'}, function() {
     *     alert("div1 element background color is black");
     * });
     * // 获取div1元素的背景颜色
     * var bgc = giant.dom.css('#div1', 'background-color');
     * // bgc == '#000000'
     * </pre>
     * @param {String|Element|jQuery} el 要获取或设置样式的元素选择符(对象)。
     * @param {String|Object} css 要获取或设置的CSS样式属性名或集合。
     * @param {Function} callback 设置CSS样式成功后执行的回调函数。
     * @returns {Object} 返回指定元素的CSS属性的值。
     */
    css: function(el, css, callback) {
        el = $(el);
        if(giant.isString(css))
            return el.css(css.toCamel());
        else {
            el.css(css);
            if(giant.isFunction(callback))
                callback.call(el[0] || this);
        }
    },
    /**
     * 以内联样式显示元素，并执行指定的回调函数。
     * @param {String|Element|jQuery} el 指定的元素。
     * @param {Function} callback 显示元素后执行的回调函数。
     */
    inline: function(el, callback) {
        this.css(el, {display:'inline'}, callback);
    },
    /**
     * 以块级样式显示元素，并执行指定的回调函数。
     * @param {String|Element|jQuery} el 指定的元素。
     * @param {Function} callback 显示元素后执行的回调函数。
     */
    block: function(el, callback) {
        this.css(el, {display:'block'}, callback);
    },
    /**
     * 隐藏指定的元素，并执行指定的回调函数。
     * @param {String|Element|jQuery} el 指定的元素。
     * @param {Function} callback 隐藏元素后执行的回调函数。
     */
    hidden: function(el, callback) {
        this.css(el, {display:'none'}, callback);
    },
    /**
     * 获取或设置指定元素相对于document的绝对坐标。
     * @example
     * <pre>
     * // &lt;div id="div1"&gt;&lt;/div&gt;
     * var div1Pos = giant.dom.xy('#div1');
     * giant.dom.xy('#div1', [100, 100], function(pos) {
     *     alert(this.id + ' ' + pos);
     * });
     * </pre>
     * @param {String|Element|jQuery} el 指定的元素。
     * @param {Array} pos 要设置的坐标数组。
     * @param {Function} callback (可选的)设置坐标后执行的回调函数。
     * @param {Array} args (可选的)回调函数的参数。
     * @returns {Array} 返回指定元素的绝对坐标。
     */
    xy: function(el, pos, callback, args) {
        el = $(el);
        if(pos) {
            var stylePosition = el.css('position');
            if( stylePosition === 'static' ) {
                stylePosition = 'relative';
                el.css({position:stylePosition});
            }
            var exy = this.xy(el);
            if( exy === false ) return false;
            var delta = [parseInt(el.css('left'), 10), parseInt(el.css('top'), 10)];
            if(isNaN(delta[0]))
                delta[0] = stylePosition == 'relative' ? 0 : el[0].offsetLeft;
            if(isNaN(delta[1]))
                delta[1] = stylePosition == 'relative' ? 0 : el[0].offsetTop;
            if(pos[0] !== null)
                el.css('left', pos[0] - exy[0] + delta[0] + 'px');
            if(pos[1] !== null)
                el.css('top', pos[1] - exy[1] + delta[1] + 'px');
            args = giant.isArray(args) ? args : [];
            if(giant.isFunction(callback))
                callback.apply(el[0], args);
       } else {
           pos = el.offset();
           return [pos['left'], pos['top']];
       }
    },
    /**
     * 获取指定元素<tt>el</tt>在<code>document</code>中的范围。
     * <pre>
     * 范围的数据类型：
     * {
     *     t: tv, // 上边距视窗顶部的距离
     *     r: rv, // 右边距视窗左部的距离
     *     b: bv, // 下边距视窗顶部的距离
     *     l: lv, // 左边距视窗左部的距离
     * }
     * </pre>
     * @param {String|Element|jQuery} el jQuery的选择器或者元素对象或jQuery对象。
     * @returns {Object} 返回表示指定元素范围的对象。
     */
    getRange: function(el) {
        el = $(el);
        if(el.length == 0) return {t:0, r:0, b:0, l:0};
        var pos = this.xy(el);
        return {t:pos[1], r:pos[0] + el[0].offsetWidth, b:pos[1] + el[0].offsetHeight, l:pos[0]};
    },
    /**
     * 若指定的坐标在给定的元素的范围内，则返回<code>true</code>，否则返回<code>false</code>。
     * 
     * @param {String|Element|jQuery} el jQuery的选择器或者元素对象或jQuery对象。
     * @param {Array} pos 指定的坐标。
     * @returns {Boolean} 若指定的坐标在给定的元素的范围内，则为<code>true</code>，否则为<code>false</code>。
     */
    posInRange: function(el, pos) {
        var range = this.getRange(el);
        if(giant.isArray(pos)) {
            if(pos[0] >= range.l && pos[0] <= range.r &&
                    pos[1] >= range.t && pos[1] <= range.b)
                return true;
        }
        return false;
    }
};

/**
 * @class Ajax请求的返回状态值信息。
 * <strong>该类的快捷引用是：AjaxStatus</strong>，如：AjaxStatus.success
 * @name giant.Status
 */
giant.Status = {
    /**
     * 表示Ajax请求返回成功的标识。
     * @type Number
     */
    success: 1,
    /**
     * 表示Ajax请求返回失败的标识。
     * @type Number
     */
    failure: 0,
    /**
     * 表示Ajax请求发生错误的标识。
     * @type Number
     */
    error: -1
};
window.AjaxStatus = giant.Status;

/**
 * @class 关于颜色处理的便捷工具类。
 */
giant.Color = {
    reRGB: /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
    reHEX: /^#([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,
    reHEX3: /^#([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i,
    
    /**
     * 将HSB格式颜色代码转换成Hash类型的RGB格式。
     * <pre>{r:RedValue, g:GreenValue, b:BlueValue}</pre>
     * @param {Number} H 色调值。
     * @param {Number} S 饱和度值。
     * @param {Number} V 亮度值。
     * @return {Object} RGB格式的颜色代码。
     */
    hsv_to_RGB: function(H, S, V) {
        var R = 0, G = 0, B = 0;
        H = (H >= 360) ? 0 : H;
        if(S === 0) {
            R = V * 255;
            G = V * 255;
            B = V * 255;
        } else {
            var hi = Math.floor(H / 60) % 6;
            var f = H / 60 - hi;
            var p = V * (1 - S), q = V * (1 - S * f), t = V * (1 - S * (1 - f));
            switch(hi) {
                case 0:
                R = V, G = t, B = p; break;
                case 1:
                R = q, G = V, B = p; break;
                case 2:
                R = p, G = V, B = t; break;
                case 3:
                R = p, G = q, B = V; break;
                case 4:
                R = t, G = p, B = V; break;
                case 5:
                R = V, G = p, B = q; break;
                default:
                break;
            }
            R = R * 255, G = G * 255, B = B * 255;
        }
        return {r:R, g:G, b:B};
    },
    /**
     * 将RGB格式颜色转换为HSV(B)(因B与RGB中的Blue同字母，所以取为V)格式。
     * <pre>{h:HueValue, s:SaturationValue, v:BrightnessValue}</pre>
     * @param {Number} R Red。
     * @param {Number} G Green。
     * @param {Number} B Blue。
     * @return {Object} HSV(B)格式的颜色代码。{h:Hvalue, s:Svalue, v:Vvalue}
     */
    rgb_to_HSV: function(R, G, B) {
        var v_Min = Math.min(Math.min(R, G), B);
        var v_Max = Math.max(Math.max(R, G), B);
        var H = 0, S = 0, V = 0;
        if(v_Min == v_Max) {
            H = 0;
        } else if(v_Max == R && G >= B) {
            H = 60 * ((G - B) / (v_Max - v_Min));
        } else if(v_Max == R && G < B) {
            H = 60 * ((G - B) / (v_Max - v_Min)) + 360;
        } else if(v_Max == G) {
            H = 60 * ((B - R) / (v_Max - v_Min)) + 120;
        } else if(v_Max == B) {
            H = 60 * ((R - G) / (v_Max - v_Min)) + 240;
        }
        if(v_Max === 0) {
            S = 0;
        }else {
            S = 1 - (v_Min / v_Max);
        }
        var v_R = (R / 255);
        var v_G = (G / 255);
        var v_B = (B / 255);
        V = Math.max(Math.max(v_R, v_G), v_B);
        H = (H > 360) ? 0 : H;
        return {h:Math.round(H), s:S, v:V};
    },
    /**
     * 将HTML的颜色代码转换成RGB格式颜色代码。
     * @param {String} color HTML格式的颜色代码。(firefox: rgb(r, g, b), ie: #RRGGBB)
     * @return {Object} Hash格式的RGB格式颜色代码。
     */
    hex_to_RGB: function(color) {
        if( color === 'transparent')
            return {r:NaN, g:NaN, b:NaN};
        var len = color.length, R, G, B;
        if(this.reRGB.exec(color)) { // mozilla(firefox)
            R = parseInt(Math.round(RegExp.$1));
            G = parseInt(Math.round(RegExp.$2));
            B = parseInt(Math.round(RegExp.$3));
            return {r:R, g:G, b:B};
        } else if(this.reHEX.exec(color)) { // #XXXXXX
            R = parseInt('0x' + RegExp.$1);
            G = parseInt('0x' + RegExp.$2);
            B = parseInt('0x' + RegExp.$3);
            return {r:R, g:G, b:B};
        } else if(this.reHEX3.exec(color)) { // #XXX 简写的颜色代码
            R = parseInt('0x' + RegExp.$1 + RegExp.$1);
            G = parseInt('0x' + RegExp.$2 + RegExp.$2);
            B = parseInt('0x' + RegExp.$3 + RegExp.$3);
            return {r:R, g:G, b:B};
        } else {
            return {r:NaN, g:NaN, b:NaN};
        }
    },
    /**
     * 将RGB格式颜色代码转换成HTML的颜色代码。
     * @param {Object} rgb ({r:RedValue, g:GreenValue, b:BlueValue})
     * @returns {String} 十六进制的HTML格式颜色代码。
     */
    rgb_to_HEX: function(rgb) {
        if( !rgb || !rgb.r || !rgb.g || !rgb.b )
            return 'transparent'
        if( !isFinite(rgb.r) && !isFinite(rgb.g) && !isFinite(rgb.b) )
            return 'transparent';
        else {
            var R = parseInt(Math.round(rgb.r)).toColorHex();
            var G = parseInt(Math.round(rgb.g)).toColorHex();
            var B = parseInt(Math.round(rgb.b)).toColorHex();
            return '#' + R + G + B;
        }
    },
    /**
     * 将Html中的颜色代码统一转换为16进制格式表示形式。
     * @param {String} color HTML格式的颜色代码。(firefox: rgb(r, g, b), ie: #RRGGBB)
     * @returns {String} 十六进制的HTML格式颜色代码。#RRGGBB
     */
    toHex: function(color) {
        return this.rgb_to_HEX(this.hex_to_RGB(color));
    }
};

$.fn.addSelectOptions = function(configs) {
	
};})(jQuery);/**
 * GAVC Web系统中统一的Ajax控制工具类。
 * @class Ajax控制工具类。
 * @constructor
 */
var GiantAjax = function() {};
window.GiantAjax = GiantAjax;

(function($) {

/**
 * Ajax请求的默认载入控制器前缀。
 * @type String
 */
GiantAjax.LOAD = "ajaxLoad";
/**
 * Ajax请求的默认保存控制器前缀。
 * @type String
 */
GiantAjax.SAVE = "ajaxSave";
/**
 * Ajax请求的默认更新控制器前缀。
 * @type String
 */
GiantAjax.UPDATE = "ajaxUpdate";
/**
 * Ajax请求的默认上传控制器前缀。
 * @type String
 */
GiantAjax.UPLOAD = "ajaxUpload";
/**
 * Ajax请求的默认删除控制器前缀。
 * @type String
 */
GiantAjax.DELETE = "ajaxDelete";

/**
 * 用于执行响应返回Html的Ajax请求。
 * @example
 * <pre>
 * GiantAjax.responseHtml('#div1', {
 *     url: '/profile/ajaxLoadWorkExps.do',
 *     params: { uid:'MMMMMMMMMMMMMM' },
 *     error: function(xhr, status, error) {
 *         <span class="annotate">// Ajax请求错误时，将执行该函数</span>
 *         alert(status);
 *     },
 *     before: function() {
 *         <span class="annotate">// this 表示Ajax请求传递的 options 参数
 *         // return false; 若返回 false，则取消本次Ajax请求</span>
 *         return true;
 *     },
 *     success: function() {
 *         <span class="annotate"><strong>// div1内的Html被此请求返回的Html替换后，执行的回调函数</strong>
 *         // this 表示Ajax请求传递的 options 参数</span>
 *     }
 * });
 * </pre>
 * 
 * @param {String} container 装载返回的Html代码的Html容器Id。
 * @param {Object} options Ajax请求的相关参数。<br>
 *         options.async  --&gt;  是否异步发送Ajax请求 <strong>（可选）</strong><br>
 *         options.url    --&gt;  Ajax请求的URL地址   <br>
 *         options.params --&gt;  Ajax请求所传递的参数 <strong>（可选）</strong><br>
 *         options.before --&gt;  Ajax请求发送前执行的回调函数，若返回false，则中断请求。<strong>（可选）</strong><br>
 *         options.success--&gt;  Ajax请求完成，Html代码已装载完成后，执行的回调函数。<strong>（可选）</strong><br>
 *         options.error  --&gt;  Ajax请求发生错误时，执行的回调函数。<strong>（可选）</strong>
 */
GiantAjax.responseHtml = function(container, options) {
    var requestUrl = options.url;
    if(!requestUrl.startsWith('http://'))
        requestUrl = Path['domain'] + requestUrl;
    container = container.startsWith('#') ? container : '#' + container;
    options.params = options.params || {};
    options.params.format = 'html';
    var ajaxOptions = {
        type: 'GET',
        async: options.async || true,
        cache:options.cache||false,
        url: requestUrl,
        data: options.params,
        success: function(shtml) {
            $(container).html(shtml);
            if(giant.isFunction(options.success))
                options.success.call(ajaxOptions);
        },
        dataType: options.params.format
    };
    if(giant.isFunction(options.error))
        ajaxOptions.error = options.error;
    if(giant.isFunction(options.before))
        ajaxOptions.beforeSend = options.before;
    $.ajax(ajaxOptions);
};

/**
 * 用于执行响应返回Html的Ajax请求。
 * @example
 * <pre>
 * GiantAjax.requestHtml({
 *     url: '/profile/ajaxLoadWorkExps.do',
 *     params: { uid:'MMMMMMMMMMMMMM' },
 *     error: function(xhr, status, error) {
 *         <span class="annotate">// Ajax请求错误时，将执行该函数</span>
 *         alert(status);
 *     },
 *     before: function() {
 *         <span class="annotate">// this 表示Ajax请求传递的 options 参数
 *         // return false; 若返回 false，则取消本次Ajax请求</span>
 *         return true;
 *     },
 *     success: function(html) {
 *         <span class="annotate"><strong>// 成功请求后，执行的回调函数</strong>
 *         // this 表示Ajax请求传递的 options 参数</span>
 *     }
 * });
 * </pre>
 * 
 * @param {String} container 装载返回的Html代码的Html容器Id。
 * @param {Object} options Ajax请求的相关参数。<br>
 *         options.async  --&gt;  是否异步发送Ajax请求 <strong>（可选）</strong><br>
 *         options.url    --&gt;  Ajax请求的URL地址   <br>
 *         options.params --&gt;  Ajax请求所传递的参数 <strong>（可选）</strong><br>
 *         options.before --&gt;  Ajax请求发送前执行的回调函数，若返回false，则中断请求。<strong>（可选）</strong><br>
 *         options.success--&gt;  Ajax请求完成，执行的回调函数。<strong>（可选）</strong><br>
 *         options.error  --&gt;  Ajax请求发生错误时，执行的回调函数。<strong>（可选）</strong>
 */
GiantAjax.requestHtml = function(options) {
	var requestUrl = options.url;
    if(!requestUrl.startsWith('http://'))
        requestUrl = Path['domain'] + requestUrl;
    container = container.startsWith('#') ? container : '#' + container;
    options.params = options.params || {};
    options.params.format = 'html';
    var ajaxOptions = {
        type: 'GET',
        async: options.async || true,
        cache:options.cache||false,
        url: requestUrl,
        data: options.params,
        success: options.success,
        dataType: options.params.format
    };
    if(giant.isFunction(options.error))
        ajaxOptions.error = options.error;
    if(giant.isFunction(options.before))
        ajaxOptions.beforeSend = options.before;
    $.ajax(ajaxOptions);
};

/**
 * 用于执行响应返回JSON的Ajax请求。
 * @example
 * <pre>
 * GiantAjax.responseJson({
 *     url: '/profile/ajaxLoadWorkExps.do',
 *     params: { uid:'MMMMMMMMMMMMMM' },
 *     error: function(xhr, status, error) {
 *         <span class="annotate">// Ajax请求错误时，将执行该函数</span>
 *         alert(status);
 *     },
 *     before: function() {
 *         <span class="annotate">// this 表示Ajax请求传递的 options 参数
 *         // return false; 若返回 false，则取消本次Ajax请求
 *         <strong>// 该方法与<u>jQuery</u>的beforeSend相同</strong></span>
 *         return true;
 *     },
 *     success: function(jsonData) {
 *         <span class="annotate"><strong>// Ajax成功执行后的回调函数</strong></span>
 *     }
 * });
 * <span class="annotate"><strong>// 跨域Ajax请求</strong></span>
 * GiantAjax.responseJson({
 *     crossdomain: true,
 *     url: '/profile/ajaxLoadWorkExps.do',
 *     params: { uid:'MMMMMMMMMMMMMM' },
 *     success: function(jsonData) {
 *         <span class="annotate"><strong>// Ajax成功执行后的回调函数</strong></span>
 *     }
 * });
 * <span class="annotate">// 跨域Ajax请求返回的JSON
 * // jsonCallback是事先定义要执行的函数名(该函数名根据需要进行更改)</span>
 * jsonCallback(JSON数据)
 * </pre>
 * 
 * @param {Object} options Ajax请求的相关参数。<br>
 *         options.crossdomain --&gt; 是否进行跨域请求，若为true，请参看jQuery的getJSON方法的机制<br>
 *         options.async  --&gt;  是否异步发送Ajax请求 <strong>（可选）</strong><br>
 *         options.url    --&gt;  Ajax请求的URL地址   <br>
 *         options.params --&gt;  Ajax请求所传递的参数 <strong>（可选）</strong><br>
 *         options.before --&gt;  Ajax请求发送前执行的回调函数，若返回false，则中断请求。<strong>（可选）</strong><br>
 *         options.success--&gt;  Ajax请求完成，Html代码已装载完成后，执行的回调函数。<strong>（可选）</strong><br>
 *         options.error  --&gt;  Ajax请求发生错误时，执行的回调函数。<strong>（可选）</strong>
 */
GiantAjax.responseJson = function(options) {
    var requestUrl = options.url;
    if(!requestUrl.startsWith('http://'))
        requestUrl = Path['domain'] + requestUrl;
    var hasParams = requestUrl.indexOf('?') >= 0;
    options.async = giant.isBool(options.async) ? options.async : true;
    options.params = options.params || {};
    options.params.format = 'json';
    var ajaxOptions = {
            type: options.type || 'GET',
            async: options.async,
            cache:options.cache||false,
            url: requestUrl,
            data: options.params,
            success: options.success || function(jdata) {},
            dataType: options.params.format
        };
    if(options.crossdomain) {
    	requestUrl = hasParams ? requestUrl + '&jsoncallback=?' : 
                requestUrl + '?jsoncallback=?';
        ajaxOptions.url = requestUrl;
    }
    if(giant.isFunction(options.error))
        ajaxOptions.error = options.error;
    if(giant.isFunction(options.before))
        ajaxOptions.beforeSend = options.before;
    $.ajax(ajaxOptions);
};

/**
 * 用于执行FORM表单的Ajax方式提交。
 * @example
 * <pre>
 * <span class="annotate"><strong>// FORM表单的Ajax方式提交 </strong></span>
 * GiantAjax.formSubmit('#form_login', {
 *     <span class="annotate"><strong>// 此方法通常只做表单数据验证，和一些数据的前期处理</strong></span>
 *     beforeSubmit: function() {
 *         if(this.userAccount.value=='' || this.userPassword.value=='') {
 *             alert('请输入对应的账号和密码！');
 *             return false;
 *         }
 *         return true;
 *     },
 *     success: function(data) { alert(data.message); },
 *     dataType: 'json' 
 * });
 * </pre>
 * 
 * @param {String} formId 要执行Ajax提交的表单Id(前缀可包含#)。
 * @param {Object} options Ajax请求的相关参数。<br>
 *         options.dataType     --&gt; Ajax提交表单成功后，返回的数据类型(json,html,text...)。<strong>默认为JSON（可选）</strong><br>
 *         options.beforeSubmit --&gt; Ajax提交表单之前，执行的回调函数，<strong>通常用于验证表单数据（可选）</strong><br>
 *         options.success      --&gt; Ajax提交表单成功后，执行的回调函数。<br>
 *         options.data         --&gt; Ajax提交表单时，附加的额外的参数。<strong>（可选）</strong><br>
 *         options.error  --&gt;  Ajax请求发生错误时，执行的回调函数。<strong>（可选）</strong>
 */
GiantAjax.formSubmit = function(formId, options) {
	var jForm = formId.startsWith('#') ? $(formId) : $('#' + formId);
	options = giant.extend({
		beforeSubmit: function() { return true; },
		success: function(data) {}
	}, options);
	options.params = options.params || {};
    options.params.format = 'json';
	if(giant.isFunction(options.beforeSubmit))
	    if(options.beforeSubmit.call(jForm) === false)
	        return;
	var jFormOptions = {
		data: options.params,
		dataType: options.dataType || options.params.format,
		success: function(data) {
			options.success.call(jFormOptions, data);
		}
	};
	jForm.ajaxSubmit(jFormOptions);
};

})(jQuery);